package com.more.db.core;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.more.db.core.model.DataSourceEnum;
import com.more.db.core.model.DbCorpEnum;
import com.more.db.core.model.DbServerEnum;
import com.more.db.core.model.InitDataSourceModel;

import javax.sql.DataSource;
import java.sql.*;
import java.util.*;

/**
 * @ClassName InitDataSource
 * @Description TODO
 * @Author yyliu
 * @Date 2018/12/10 16:10
 * @Version 1.0
 **/
public class InitDataSource {

    public static final String DEFAULT_DB_NAME = "console";

    private static final String DB_SERVER_SQL = "select * from t_console_db_server ";

    private static final String DB_CORP_SQL = "select * from t_console_db_corp ";

    public static Map<Object, Object> targetDataSources(InitDataSourceModel model, String driverClassName) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        Map<String, DataSource> dataSourceMap = getDateSourceMap(model.getDbServerList(), driverClassName);
        for (Map.Entry<String, DataSource> sourceMap : dataSourceMap.entrySet()) {
            targetDataSources.put(sourceMap.getKey(), sourceMap.getValue());
        }
        Map<String, String> corpDbMap = initCorpDbRelation(model.getDbCorpList());
        for (Map.Entry<String, String> sourceMap : corpDbMap.entrySet()) {
            DatabaseContextHolder.setCorpDbNameMap(sourceMap.getKey(), sourceMap.getValue());
        }

        return targetDataSources;
    }

    public static Map<String, String> initCorpDbRelation(List<Map<String, Object>> dbCorpList) {
        Map<String, String> dataMap = new HashMap<>();
        if (null != dbCorpList && dbCorpList.size() > 0) {
            for (Map<String, Object> dbCorp : dbCorpList) {
                dataMap.put(dbCorp.get(DbCorpEnum.CORP_CODE.getName()).toString(),
                        dbCorp.get(DbCorpEnum.DB_NAME.getName()).toString());
            }
        }
        return dataMap;
    }

    public static Map<String, DataSource> getDateSourceMap(List<Map<String, Object>> dbList, String driverClassName) {

        Map<String, DataSource> dataMap = new HashMap<>();
        if (null != dbList && dbList.size() > 0) {
            for (Map<String, Object> db : dbList) {
                Properties props = new Properties();
                props.put(DataSourceEnum.DRIVER_CLASS_NAME.getName(), driverClassName);
                props.put(DataSourceEnum.DB_URL.getName(), db.get(DbServerEnum.DB_URL.getName()));
                props.put(DataSourceEnum.DB_USERNAME.getName(), db.get(DbServerEnum.DB_USERNAME.getName()));
                props.put(DataSourceEnum.DB_PASSWORD.getName(), db.get(DbServerEnum.DB_PASSWORD.getName()));
                DataSource dataSource = null;
                try {
                    dataSource = DruidDataSourceFactory.createDataSource(props);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                dataMap.put(db.get(DbServerEnum.DB_NAME.getName()).toString(), dataSource);
            }
        }

        return dataMap;
    }

    public static InitDataSourceModel getInitDataSourceModel(DataSource consoleDataSource) {
        InitDataSourceModel model = InitDataSourceModel.newInstance();
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            connection = consoleDataSource.getConnection();
            statement = connection.createStatement();
            rs = statement.executeQuery(DB_SERVER_SQL);
            List<Map<String, Object>> dbServerList = contractResultSetDataList(rs);
            model.setDbServerList(dbServerList);
            rs = statement.executeQuery(DB_CORP_SQL);
            List<Map<String, Object>> dbCorpList = contractResultSetDataList(rs);
            model.setDbCorpList(dbCorpList);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (null != rs) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != statement) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != connection) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return model;
    }

    private static List<Map<String, Object>> contractResultSetDataList(ResultSet rs) throws SQLException {
        List<Map<String, Object>> dataList = new ArrayList<>();
        ResultSetMetaData md = rs.getMetaData(); //获得结果集结构信息,元数据
        int columnCount = md.getColumnCount();   //获得列数
        while (rs.next()) {
            Map<String, Object> rowData = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                rowData.put(md.getColumnName(i), rs.getObject(i));
            }
            dataList.add(rowData);
        }
        return dataList;
    }
}
